<!--
 * @Descripttion: 课堂分析详情-学生行为-就座人数
 * @version: V1.0.0.1
 * @Author: zhaozhenzhuo
 * @Date: 2025-10-28 18:39:35
 * @LastEditors: zhaozhenzhuo
 * @LastEditTime: 2025-10-28 18:39:35
-->
<template>
	<div class="seating-num-wrapper">
		<div class="module-title-wrapper">
			<p>就座人数</p>
			<img v-if="false" src="@/assets/images/lessonAnalysisDetails/text-edit-normal.png" />
		</div>
		<div class="attendance-wrapper">
			<div class="lesson-attendance">
				<div class="detail">
					<p>
						本堂课应到<span class="active"
							>{{
								lessonAttend?.shouldStudentNum || lessonAttend?.shouldStudentNum === 0
									? lessonAttend.shouldStudentNum
									: '-'
							}}人</span
						>，实到<span class="active"
							>{{
								lessonAttend?.attendanceStudentNum || lessonAttend?.attendanceStudentNum === 0
									? lessonAttend.attendanceStudentNum
									: '-'
							}}人</span
						>，缺勤<span class="red">{{ lessonAttend?.notAttendance }}人</span>，课堂出勤率<span
							class="green"
							>{{
								Number.isFinite(lessonAttend?.attendanceStudentRate)
									? Number(((lessonAttend?.attendanceStudentRate || 0) * 100).toFixed(1))
									: '-'
							}}%</span
						>
						<template v-if="attendanceConfig">
							<span v-if="lessonAttend?.lateNum"
								>，迟到<span class="red">{{ lessonAttend.lateNum }}人</span></span
							><span v-else-if="lessonAttend?.lateNum === 0 && lessonAttend?.leaveEarlyNum !== 0"
								>，无迟到情况</span
							><span v-else-if="lessonAttend?.lateNum !== 0"
								>，迟到<span class="red">-人</span></span
							>
							<span v-if="lessonAttend?.leaveEarlyNum"
								>，早退<span class="red">{{ lessonAttend.leaveEarlyNum }}人</span></span
							><span v-else-if="lessonAttend?.leaveEarlyNum === 0 && lessonAttend?.lateNum !== 0"
								>，无早退情况</span
							><span v-else-if="lessonAttend?.leaveEarlyNum !== 0"
								>，早退<span class="red">-人</span></span
							>
							<span v-if="lessonAttend?.lateNum === 0 && lessonAttend?.leaveEarlyNum === 0"
								>，无迟到早退情况</span
							> </template
						>。
					</p>
				</div>
				<img class="attend-img" :src="attendImg" @click="onLookDetailHandle(0)" />
			</div>
			<div class="sitting-front">
				<div class="detail">
					<p>
						本堂课前排就座率<span class="active"
							>{{
								Number.isFinite(lessonAttend?.frontStudentRate)
									? Number(((lessonAttend?.frontStudentRate || 0) * 100).toFixed(1))
									: '-'
							}}%</span
						><span
							v-if="
								Number.isFinite(lessonAttend?.frontStudentRate) &&
								typeof lessonAttend?.frontStudentRate === 'number' &&
								lessonAttend?.frontStudentRate >= 0.9
							"
							>，前排基本坐满，学习氛围非常好</span
						><span
							v-else-if="
								Number.isFinite(lessonAttend?.frontStudentRate) &&
								typeof lessonAttend?.frontStudentRate === 'number' &&
								lessonAttend?.frontStudentRate >= 0.6 &&
								lessonAttend?.frontStudentRate < 0.9
							"
							>，前排人数较多，学习氛围良好</span
						><span
							v-else-if="
								Number.isFinite(lessonAttend?.frontStudentRate) &&
								typeof lessonAttend?.frontStudentRate === 'number' &&
								lessonAttend?.frontStudentRate >= 0.3 &&
								lessonAttend?.frontStudentRate < 0.6
							"
							>，前排人数较少，建议老师引导学生前排就座</span
						><span
							v-else-if="
								Number.isFinite(lessonAttend?.frontStudentRate) &&
								typeof lessonAttend?.frontStudentRate === 'number' &&
								lessonAttend?.frontStudentRate >= 0 &&
								lessonAttend?.frontStudentRate < 0.3
							"
							>，前排人数非常少，建议老师引导学生前排就座</span
						>。
					</p>
				</div>
				<img class="attend-img" :src="frontAttendImg" @click="onLookDetailHandle(1)" />
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { ref, nextTick, watch, computed, onBeforeUnmount } from 'vue';
import type {
	CourseListItemType,
	LessonAttendType,
	PicUrlItemType,
	AICEConfigInfoType,
	PreviewInfoType
} from './SeatingNum.type';
import { getErrorMessage, getAILessonAttendAPI } from '@/api/index';
import { isJSONString } from '@/assets/js/utils';

const props = withDefaults(
	defineProps<{
		lessonInfo: CourseListItemType | null;
		aiceConfigInfo: AICEConfigInfoType | null;
	}>(),
	{
		lessonInfo: null,
		aiceConfigInfo: null
	}
);

const emit = defineEmits<{
	(e: 'previewShow', info: PreviewInfoType): void;
}>();

// 考勤迟到早退配置项
const attendanceConfig = computed(() => props.aiceConfigInfo?.analysisLateAndEarly || 0);

watch(
	() => props.lessonInfo,
	(val) => {
		if (val) {
			nextTick(() => {
				getAILessonAttend();
			});
		}
	},
	{ immediate: true }
);

const resizeObserver = ref<ResizeObserver | null>(null);
// 初始化
const setHeight = () => {
	/* 将前排就座文字高度调整到和课堂出勤一致 */
	// 监听元素大小变化
	const _attendanceRef: HTMLDivElement | null = document.querySelector(
		'.lesson-attendance .detail'
	);
	const _frontRef: HTMLDivElement | null = document.querySelector('.sitting-front .detail');
	const _smallRef =
		(_attendanceRef?.clientHeight || 0) <= (_frontRef?.clientHeight || 0)
			? _attendanceRef
			: _frontRef;
	const _bigRef =
		(_attendanceRef?.clientHeight || 0) <= (_frontRef?.clientHeight || 0)
			? _frontRef
			: _attendanceRef;
	resizeObserver.value = new ResizeObserver(() => {
		// 当DOM元素的宽高发生变化时执行回调函数
		if (_smallRef && _bigRef) {
			const _height = _bigRef.clientHeight;
			_smallRef.style.height = `${_height}px`;
		}
	});
	if (_bigRef) {
		resizeObserver.value.observe(_bigRef);
	}
};

onBeforeUnmount(() => {
	// 组件销毁时停止观察
	if (resizeObserver.value) {
		resizeObserver.value.disconnect();
	}
});

// 出勤信息
const lessonAttend = ref<LessonAttendType | null>(null);
// 出勤图片
const attendImg = ref<string>('static/img/ai-default.jpg');
// 前排就座率图片
const frontAttendImg = ref<string>('static/img/ai-default.jpg');
// 出勤图片列表
const picUrlList = ref<PicUrlItemType[] | string>([]);
// 查询课堂出勤信息
const getAILessonAttend = async () => {
	try {
		const data = await getAILessonAttendAPI(props.lessonInfo?.code as string);

		lessonAttend.value = data || null;

		nextTick(() => {
			setHeight();
		});
		// 获取出勤图片
		if (lessonAttend.value.picUrl) {
			// 判断是否是JSON字符串
			const _picUrlList = isJSONString(lessonAttend.value.picUrl);
			if (_picUrlList) {
				// 解析为数组保存
				picUrlList.value = _picUrlList as PicUrlItemType[];
			} else {
				// 直接保存为字符串
				picUrlList.value = lessonAttend.value.picUrl;
			}
			isImgUrlValid(
				_picUrlList
					? (picUrlList.value as PicUrlItemType[])[0]?.picUrl
					: (picUrlList.value as string)
			)
				.then((result) => {
					if (result) {
						attendImg.value = _picUrlList
							? (picUrlList.value as PicUrlItemType[])[0]?.picUrl
							: (picUrlList.value as string);
						frontAttendImg.value = _picUrlList
							? (picUrlList.value as PicUrlItemType[])[0]?.picUrl
							: (picUrlList.value as string);
					} else {
						attendImg.value = 'static/img/ai-default.jpg';
						frontAttendImg.value = 'static/img/ai-default.jpg';
					}
				})
				.catch(() => {
					attendImg.value = 'static/img/ai-default.jpg';
					frontAttendImg.value = 'static/img/ai-default.jpg';
				});
		} else {
			attendImg.value = 'static/img/ai-default.jpg';
			frontAttendImg.value = 'static/img/ai-default.jpg';
		}
		// 计算缺勤人数
		lessonAttend.value.notAttendance =
			lessonAttend.value.shouldStudentNum - lessonAttend.value.attendanceStudentNum ||
			lessonAttend.value.shouldStudentNum - lessonAttend.value.attendanceStudentNum === 0
				? lessonAttend.value.shouldStudentNum - lessonAttend.value.attendanceStudentNum
				: '-';
		if (
			typeof lessonAttend.value.notAttendance === 'number' &&
			lessonAttend.value.notAttendance < 0
		) {
			lessonAttend.value.notAttendance = 0;
		}
	} catch (err) {
		console.error(getErrorMessage(err));
		// 使用默认图片
		attendImg.value = 'static/img/ai-default.jpg';
		frontAttendImg.value = 'static/img/ai-default.jpg';
	}
};

// 判断图片地址是否存在 有效返回true, 无效返回false
const isImgUrlValid = (imgurl: string) => {
	return new Promise((resolve, reject) => {
		const ImgObj = new Image(); // 判断图片是否存在
		ImgObj.src = imgurl;
		ImgObj.onload = (res) => {
			resolve(res);
		};
		ImgObj.onerror = (err) => {
			reject(err);
		};
	}).catch((err) => {
		console.error(getErrorMessage(err));
	});
};

// 预览信息
const previewInfo = ref<{
	transFileUrl: PicUrlItemType[] | string;
	type?: number;
	name?: string;
} | null>(null);
// 点击图片 type=0课堂出勤图片 type=1前排就座图片
const onLookDetailHandle = (type: number) => {
	previewInfo.value = {
		transFileUrl: picUrlList.value
	};
	if (typeof picUrlList.value === 'object') {
		previewInfo.value.type = 2;
	} else {
		previewInfo.value.type = 1;
	}
	if (type === 0) {
		previewInfo.value.name = '课堂出勤情况';
	} else {
		previewInfo.value.name = '学生前排就座情况';
	}
	emit('previewShow', previewInfo.value as PreviewInfoType);
};
</script>

<style lang="scss" scoped>
.seating-num-wrapper {
	.attendance-wrapper {
		display: flex;
		justify-content: space-between;
		gap: 2rem;
		margin-top: 1.5rem;
		width: 100%;
	}
	.detail {
		margin-top: 0 !important;
	}

	.lesson-attendance,
	.sitting-front {
		flex: 1;
		height: fit-content;

		.attend-img {
			display: block;
			width: 100%;
			aspect-ratio: 16 / 9;
			cursor: pointer;
		}
	}
}
</style>
